import requests
from hashlib import sha1
from datetime import datetime
import json
from flask import request
from flask import render_template
from flask import redirect
from flask import jsonify
from flask import make_response
from itsdangerous import TimedJSONWebSignatureSerializer
from itsdangerous import BadSignature

from . import user
from . import app
from . import auth

from . import appid
from . import token
from . import secret
from .auth import login_url


@app.route('/')
def index():
    sig = request.args.get('signature', False)
    timestamp = request.args.get('timestamp', False)
    nonce = request.args.get('nonce', False)
    echostr = request.args.get('echostr', False)

    if sig is False or timestamp is False or nonce is False or echostr is False:
        return jsonify(err=403, msg="param missing")
    list_1 = [token, timestamp, nonce]
    list_1.sort()

    # data = sorted([token, timestamp, nonce], key=str.lower)
    str = list_1[0] + list_1[1] + list_1[2]

    hash_str = sha1()
    hash_str.update(str.encode('utf-8'))

    # map(hash.update, list_1)
    hash_str = hash_str.hexdigest()
    if hash_str == sig:
        return echostr
    else:
        return "failed"


@app.route('/pre_login')
def pre_login():
    code = request.args.get('code', False)
    if code is False:
        return jsonify(err=403, msg="Access Deny!")

    state = request.args.get('state')

    data = requests.get('https://api.weixin.qq.com/sns/oauth2/access_token', params={
        'appid': appid,
        'secret': secret,
        'code': code,
        'grant_type': 'authorization_code'
    })

    data.encoding = 'utf-8'

    data_json = json.loads(data.text)
    access_token = data_json['access_token']
    refresh_token = data_json['refresh_token']

    openid = data_json['openid']

    data = requests.get('https://api.weixin.qq.com/sns/userinfo', params={
        'access_token': access_token,
        'openid': openid,
        'lang': 'zh_CN'
    })
    data.encoding = 'utf-8'
    data_json = json.loads(data.text)
    if 'errcode' in data:
        return 'Access Deny! '

    nickname = data_json['nickname']

    if user.has_user(openid) == False:
        user.add_user(openid, nickname, access_token)
    else:
        current_user = user.get_user(openid)
        if current_user == None:
            return "No user"

    s = TimedJSONWebSignatureSerializer(token, expires_in=7200)
    auth_str = s.dumps(openid).decode('utf-8')

    response = make_response()

    response.status_code = 302
    response.headers.add('Location', 'https://api.boot.pw/index')
    response.set_cookie('auth', value=auth_str, path='/', max_age=7200)

    return response


@app.route('/index')
@auth.token_required
def check_index():
    # get user info
    auth_str = request.cookies['auth']
    try:
        s = TimedJSONWebSignatureSerializer(token)
        openid = s.loads(auth_str)
    except BadSignature:
        return redirect(login_url)


    user_info = user.get_user(openid)
    if user_info == None:
        return redirect(login_url)

    checked_day = user_info[6]
    exp = user_info[5]

    return render_template('index.html', day=checked_day, exp=exp)


@app.route('/check', methods=['POST'])
@auth.token_required
def check():
    cookies = request.cookies
    if 'auth' in cookies:

        auth_str = cookies['auth']
        openid = None
        try:
            s = TimedJSONWebSignatureSerializer(token)
            openid = s.loads(auth_str)
        except BadSignature:
            return jsonify(err=1, msg="cookies error")

        time_now = datetime.now()
        # total day
        today = int((time_now.timestamp() + (3600 * 8)) / (3600 * 24))

        time_last = datetime.fromtimestamp(user.get_last_check_time(openid))
        day_last = int((time_last.timestamp() + (3600 * 8)) / (3600 * 24))
        if today <= day_last:
            return jsonify(err=9, msg="U have checked")
        else:
            cur_hour = time_now.hour
            cur_minute = time_now.minute

            now_minute = cur_hour * 60 + cur_minute

            if now_minute in range(360, 360 + 30):
                exp = 50
            elif now_minute in range(390, 390 + 60):
                exp = 30
            elif now_minute in range(450, 450 + 60):
                exp = 20
            elif now_minute in range(510, 510 + 60):
                exp = 10
            elif now_minute <= 360:
                return jsonify(err=5, msg="out of time")
            elif now_minute >= 570:
                return jsonify(err=4, msg="timeout")
            else:
                exp = 0

            user.check(openid, exp)
            return jsonify(err=0, msg="Success")

    else:
        return jsonify(err=1, msg="cookies error")

